<?php
/**
 * Created by PhpStorm.
 * User: zyark
 * Date: 2018/3/31
 * Time: 15:57
 */

namespace app\index\logic;


use app\common\utils\Constant;
use app\common\utils\IDCardUtils;
use app\common\utils\SmsUtils;
use app\common\utils\WeChatUtils;
use Exception;
use think\cache\driver\Redis;
use think\Config;
use think\Db;
use think\Log;

class UserLogic
{

    static private $instance;

    static public function getInstance(){
        if (!self::$instance instanceof self) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * 根据token获取用户信息
     * @param $token
     * @return array|false|\PDOStatement|string|\think\Model
     */
    public function getUserByToken($token){
        $user_id = $this->getUserIdByToken($token);
        $user = $this->getUserById($user_id);
        if(!$user){
            return array('status'=>0);
        }
        $user['token'] = $token;
        return array('status'=>1,'data'=>$user);
    }

    /**
     * 获取用户信息 通过id
     * @param $user_id
     * @return array|false|\PDOStatement|string|\think\Model
     */
    public function getUserById($user_id){
        $user = model('User')
            ->where(array('id'=>$user_id))
            ->field(['username','password', 'salt', 'token','email','loginfailure'], true)
            ->find();
        return $user;
    }

    /**
     * 获取用户id token
     * @param $token
     * @return mixed
     */
    public function getUserIdByToken($token){
        $redis = new Redis();
        $user_id = $redis->get($token);
        return $user_id;
    }

    /**
     * 获取用户信息 通过微信授权code
     * @param $code
     * @return mixed
     */
    public function getUserByCode($code){
        Db::startTrans();
        try {
            $we_chat = Config::get('WeChat');
            $utils = new WeChatUtils($we_chat['app_id'], $we_chat['app_secret'], $we_chat['token']);
            $result = $utils->getHtmlAccessToken($code);
            $userInfo = $utils->getUserInfo($result->access_token, $result->openid);
            $user = $this->saveOrUpdateUser($result->openid, $userInfo);
            $redis = new Redis();
            $token = $this->generateToken($user['openid'], $user['id']);
            $redis->set($token, $user['id']);
            $user['token'] = $token;
            Db::commit();
            return array('status'=>1,'data'=>$user);
        }catch (Exception $e){
            Db::rollback();
            return array('status'=>0,'error'=>$e->getMessage());
        }
    }

    /**
     * 绑定房产
     * @param $user_id int 用户id
     */
    private function bindHousePropertyByUser($user_id){
        $owner = model('Owner')->where(array('user_id'=>$user_id))->find();
        if($owner){
            $this->bindHouseProperty($owner['id'],$user_id);
        }
    }

    /**
     * 创建或更新用户信息
     * @param $open_id
     * @param $user_info
     * @return $this|array|false|\PDOStatement|string|\think\Model
     */
    public function saveOrUpdateUser($open_id,$user_info){
        $open_id = $open_id.'';
        $user = model('User')
            ->field(['username','password', 'salt', 'token','email','loginfailure'], true)
            ->where(array('openid'=>$open_id))
            ->find();
        if(!$user){
            //创建用户
            $user_info = $this->makeUser($user_info);
            $user_info['createtime'] = time();
            $user_info['logintime'] = time();
            $user_info['openid'] = $open_id;
            $user_info['user_type'] = Constant::USER_TYPE_OWNER;
            $user_info['property_id'] = 0;
            $user = model('User')->create($user_info);
        }else{
            $user_info = $this->makeUser($user_info);
            $user_info['updatetime'] = time();
            $user_info['logintime'] = time();
            $user->save($user_info);
            $this->bindHousePropertyByUser($user['id']);
        }
        return $user;
    }

    public function generateToken($open_id,$user_id){
        return substr(md5(md5($open_id) . 'key' . $user_id.''.time()), 0, 30);
    }

    private function makeUser($userInfo){
        $user = [];
        $userInfo = (array)$userInfo;
        if(isset($userInfo) && isset($userInfo['nickname'])) {
            $user['nickname'] = match_chinese($userInfo['nickname']);
            $user['avatar'] = $userInfo['headimgurl'];
            $sex = $userInfo['sex'] . '';
            $user['sex'] = $sex == '2' ? 1 : 0;
        }
        return $user;
    }

    /**
     * 绑定业主信息
     * @param $userInfo 用户信息
     * @param $userId 用户ID
     * @return mixed
     */
    public function bindUserInfo($userInfo, $userId){
        //获取用户信息判断该用户是否已绑定
        try {
            Db::startTrans();
            $result = $this->checkOwnerData($userInfo);
            $code = $this->getVerifyCodeByRedis($userId,$userInfo['phone']);
            if(!$code || $code != $userInfo['code']){
                return array('status'=>Constant::CODE_ERROR, 'msg'=>'验证码不正确');
            }
            if($result['status'] != Constant::CODE_SUCCESS){
                return $result;
            }
            $this->removeVerifyCodeByRedis($userId,$userInfo['phone']);
            $ownerCount = model('Owner')->where("user_id={$userId}")->count();
//            return array('status'=>Constant::CODE_ERROR, 'msg'=>$userId);
            if (empty($ownerCount)) {
                $owner = model('Owner')->where(array('phone' => $userInfo['phone'], 'is_bind' => Constant::BIND_NO))->find();
                if ($owner) {
                    $result = $this->checkOwner($owner,$userInfo);
                    if($result['status'] != Constant::CODE_SUCCESS){
                        return $result;
                    }
                    model('Owner')->where("id={$owner['id']}")->update([
                        'user_id' => $userId
                        , 'is_bind' => Constant::BIND_YES
                    ]);
                    $this->bindHouseProperty($owner['id'], $userId);
                } else {
                   /* $checkRe = $this->checkOwnerData($userInfo);
                    if ($checkRe['status'] == Constant::CODE_ERROR) {
                        return $checkRe;
                    }
                    $userInfo['user_id'] = $userId;
                    $userInfo['is_bind'] = Constant::BIND_YES;
                    model('Owner')->insert($userInfo);*/
                   Db::rollback();
                   return array('status'=>Constant::CODE_UNBOUNDED, 'msg'=>'未找到您的信息请联系物业录入');
                }
                Db::commit();
                return array('status'=> Constant::CODE_SUCCESS, 'msg'=>'绑定成功');
            }
            else{
                return array('status'=> Constant::CODE_ERROR, 'msg'=> '您已绑定');
            }

        }catch (Exception $e){
            Db::rollback();
            return array('status' => Constant::CODE_ERROR, 'msg'=>$e->getMessage());
        }
    }

    /**
     * 绑定房产
     * @param $ownerId int 业主ID
     * @param $userId int 用户ID
     */
    private function bindHouseProperty($ownerId, $userId){
        $ids = [];
        $houseProperty = model('HouseProperty')->where(array('owner_id'=>$ownerId))->select();
        foreach ($houseProperty as $key => $value){
            if($value['user_id'] == 0){
                $ids[] = $value['id'];
            }
        }
        if($ids){
            model('HouseProperty')->where(array('id'=>array('in', $ids)))->setField('user_id', $userId);
        }
    }

    private function checkOwner($owner,$data){
        if($owner['id_card'] != $data['id_card']){
            return array('status'=>Constant::CODE_ERROR, 'msg'=> '身份证号不匹配');
        }
        if($owner['phone'] != $data['phone']){
            return array('status'=>Constant::CODE_ERROR, 'msg'=> '手机号不匹配');
        }
        if($owner['name'] != $data['user_name']){
            return array('status'=>Constant::CODE_ERROR, 'msg'=> '业主名不匹配');
        }
        return array('status'=>Constant::CODE_SUCCESS);
    }

    /**
     * 检查业主的字段
     * @param $data
     * @return mixed
     */
    private function checkOwnerData($data){
        if(!isset($data['id_card']) || !isset($data['phone']) || !isset($data['user_name'])){
            return array('status'=>Constant::CODE_ERROR, 'msg'=> '参数不完整');
        }
        if(!isset($data['code'])){
            return array('status'=>Constant::CODE_ERROR, 'msg'=> '请填写验证码');
        }
        if(!(IDCardUtils::getInstance()->validation_filter_id_card($data['id_card']))){
            return array('status'=>Constant::CODE_ERROR, 'msg'=> '身份证格式不正确');
        }
        if(!is_mobile($data['phone'])){
            return array('status'=>Constant::CODE_ERROR, 'msg'=> '手机号格式不正确');
        }
        return array('status'=>Constant::CODE_SUCCESS, 'msg'=>'检查完成');
    }

    /**
     * 获取验证码
     * @param $phone
     * @param $user_id
     * @return array
     */
    public function getVerifyCode($phone,$user_id){
        try {
            if (empty($phone) || !is_mobile($phone)) {
                return array('status' => 2, 'msg' => '请选择输入正确的手机号！');
            }
            $create_time = $this->getCodeCreateTime($user_id);
            if ($create_time && !empty($create_time) && time() - $create_time < 60) {
                return array(['status' => 2, 'msg' => '不能重复获取！']);
            }
            $utils = SmsUtils::getInstance();
            $code = $utils->send_code($phone);
            $this->setCodeCreateTime($user_id);
            $this->setVerifyCode($user_id,$phone,$code);
            return ['status' => 1, 'msg' => '已经发送成功！'];
        }catch (Exception $e){
            Log::write('getVerifyCode:'.$e->getMessage());
            return ['status' => 0, 'error' => $e->getMessage()];
        }
    }

    /**
     * redis 设置验证码创建时间
     * @param $user_id
     */
    private function setCodeCreateTime($user_id){
        $redis = new Redis();
        $redis->set('create_time_'.$user_id,time(),65);
    }

    public function getCodeCreateTime($user_id){
        $redis = new Redis();
        return $redis->get('create_time_'.$user_id);
    }

    private function setVerifyCode($user_id,$phone,$code){
        $redis = new Redis();
        $redis->set('verify_code'.$user_id.'_'.$phone,$code,60 * 30);
    }

    /**
     * redis中获取验证码
     * @param $user_id
     * @param $phone
     * @return mixed
     */
    public function getVerifyCodeByRedis($user_id,$phone){
        $redis = new Redis();
        return $redis->get('verify_code'.$user_id.'_'.$phone);
    }

    /**
     * 清掉验证码
     * @param $user_id
     * @param $phone
     * @return bool
     */
    public function removeVerifyCodeByRedis($user_id,$phone){
        $redis = new Redis();
        return $redis->rm('verify_code'.$user_id.'_'.$phone);
    }


}